package com.psct.fragment;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragment;
import com.psct.R;
import com.psct.imageCache.ImageCache;
import com.psct.imageCache.ImageCacheManager;
import com.psct.imageCache.ImageCacheManager.ImageLoadCallBack;
import com.psct.web.HttpUtil;
import com.psct.wiget.GestureDetector;
import com.psct.wiget.ImageViewTouch;
import com.psct.wiget.PagerAdapter;
import com.psct.wiget.ScaleGestureDetector;
import com.psct.wiget.ViewPager;

public class ImageShowFragment extends SherlockFragment implements OnClickListener {
	private static final int PAGER_MARGIN_DP = 40;
	private static final String TAG = "fragment";

	ImageCache cache;

	private ViewPager mViewPager;
	private ImagePagerAdapter mPagerAdapter;
	private GestureDetector mGestureDetector;
	private ScaleGestureDetector mScaleGestureDetector;
	private TextView tvTitle;
	private boolean mPaused;
	private boolean mOnScale = false;
	private boolean mOnPagerScoll = false;
	private boolean mControlsShow = false;
	// 传入参数
	private List<String> mImageList;
	private int mPosition;

	/**
	 * 工厂方法
	 * 
	 * @param imagePathList
	 * @return
	 */
	public static ImageShowFragment newInstance(ArrayList<String> imagePathList) {

		Bundle bundle = new Bundle();
		bundle.putStringArrayList("imagePath", imagePathList);
		ImageShowFragment f = new ImageShowFragment();
		f.setArguments(bundle);
		return f;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.v(TAG, "onCreate");
		super.onCreate(savedInstanceState);
		this.setRetainInstance(true);
		mImageList=this.getArguments().getStringArrayList("imagePath");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		Log.v(TAG, "onCreateView");
		View view = inflater.inflate(R.layout.fragment_image_show, container, false);
		mViewPager = (ViewPager) view.findViewById(R.id.viewPager);
		final float scale = getResources().getDisplayMetrics().density;
		int pagerMarginPixels = (int) (PAGER_MARGIN_DP * scale + 0.5f);
		mViewPager.setPageMargin(pagerMarginPixels);
		tvTitle = (TextView) view.findViewById(R.id.tv_title);
		mPagerAdapter = new ImagePagerAdapter();
		mViewPager.setAdapter(mPagerAdapter);
		mViewPager.setOnPageChangeListener(mPageChangeListener);
		setupOnTouchListeners(mViewPager);
		mPosition = 0;
		mViewPager.setCurrentItem(mPosition, false);
		updateShowInfo();
		return view;
	}

	/**
	 * 更新标题信息
	 */
	private void updateShowInfo() {
		if (mImageList.size() > 0) {
			tvTitle.setText(String.format("%d/%d", mPosition + 1, mImageList.size()));
		}
	}

	@Override
	public void onHiddenChanged(boolean hidden) {
		Log.v(TAG, "onHiddenChanged");
		super.onHiddenChanged(hidden);
	}

	@Override
	public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
		Log.v(TAG, "onInflate");
		super.onInflate(activity, attrs, savedInstanceState);
	}

	@Override
	public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
		return super.onCreateAnimation(transit, enter, nextAnim);
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		Log.v(TAG, "onViewCreated");
		super.onViewCreated(view, savedInstanceState);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		Log.v(TAG, "onActivityCreated");
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public void onResume() {
		Log.v(TAG, "onResume");
		super.onResume();
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		Log.v(TAG, "onSaveInstanceState");
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onPause() {
		Log.v(TAG, "onPause");
		super.onPause();
	}

	@Override
	public void onDestroyView() {
		Log.v(TAG, "onDestroyView");
		super.onDestroyView();
	}

	@Override
	public void onAttach(Activity activity) {
		Log.v(TAG, "onAttach");
		super.onAttach(activity);
	}

	@Override
	public void onDetach() {
		Log.v(TAG, "onDetach");
		super.onDetach();
	}

	@Override
	public void onStart() {
		Log.v(TAG, "onStart");
		super.onStart();
		mPaused = false;
	}

	@Override
	public void onStop() {
		Log.v(TAG, "onStop");
		super.onStop();
		mPaused = true;
	}

	private void setupOnTouchListeners(View rootView) {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
			mScaleGestureDetector = new ScaleGestureDetector(this.getActivity(),
					new MyOnScaleGestureListener());
		}
		mGestureDetector = new GestureDetector(this.getActivity(), new MyGestureListener());

		OnTouchListener rootListener = new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				// NOTE: gestureDetector may handle onScroll..
				if (!mOnScale) {
					if (!mOnPagerScoll) {
						mGestureDetector.onTouchEvent(event);
					}
				}

				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
					if (!mOnPagerScoll) {
						mScaleGestureDetector.onTouchEvent(event);
					}
				}

				ImageViewTouch imageView = getCurrentImageView();
				if (!mOnScale) {
					Matrix m = imageView.getImageViewMatrix();
					RectF rect = new RectF(0, 0, imageView.mBitmapDisplayed.getBitmap().getWidth(),
							imageView.mBitmapDisplayed.getBitmap().getHeight());
					m.mapRect(rect);
					// Log.d(TAG, "rect.right: " + rect.right + ", rect.left: "
					// + rect.left + ", imageView.getWidth(): "
					// + imageView.getWidth());
					// 图片超出屏幕范围后移动
					if (!(rect.right > imageView.getWidth() + 0.1 && rect.left < -0.1)) {
						try {
							mViewPager.onTouchEvent(event);
						} catch (ArrayIndexOutOfBoundsException e) {
							// why?
						}
					}
				}

				// We do not use the return value of
				// mGestureDetector.onTouchEvent because we will not receive
				// the "up" event if we return false for the "down" event.
				return true;
			}
		};

		rootView.setOnTouchListener(rootListener);
	}

	@Override
	public void onDestroy() {
		ImageViewTouch imageView = getCurrentImageView();
		imageView.mBitmapDisplayed.recycle();
		imageView.clear();
		super.onDestroy();
	}

	private ImageViewTouch getCurrentImageView() {
		return (ImageViewTouch) mPagerAdapter.views.get((mViewPager.getCurrentItem()));
	}

	ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
		@Override
		public void onPageSelected(int position, int prePosition) {
			ImageViewTouch preImageView = mPagerAdapter.views.get(prePosition);
			if (preImageView != null) {
				preImageView.setImageBitmapResetBase(preImageView.mBitmapDisplayed.getBitmap(),
						true);
			}
			mPosition = position;

			updateShowInfo();
		}

		@Override
		public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
			// Log.d(TAG, "onPageScrolled");
			mOnPagerScoll = true;
		}

		@Override
		public void onPageScrollStateChanged(int state) {
			// Log.d(TAG, "onPageScrollStateChanged: " + state);
			if (state == ViewPager.SCROLL_STATE_DRAGGING) {
				mOnPagerScoll = true;
			} else if (state == ViewPager.SCROLL_STATE_SETTLING) {
				mOnPagerScoll = false;
			} else {
				mOnPagerScoll = false;
			}
		}

	};

	/**
	 * 一般手势识别类
	 * 
	 * @author zjingchuan
	 * 
	 */

	private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
			// Log.d(TAG, "gesture onScroll");
			if (mOnScale) {
				return true;
			}
			if (mPaused) {
				return false;
			}
			ImageViewTouch imageView = getCurrentImageView();
			imageView.panBy(-distanceX, -distanceY);
			imageView.center(true, true);

			// 超出边界效果去掉这个
			imageView.center(true, true);

			return true;
		}

		@Override
		public boolean onUp(MotionEvent e) {
			// getCurrentImageView().center(true, true);
			return super.onUp(e);
		}

		@Override
		public boolean onSingleTapConfirmed(MotionEvent e) {
			if (mControlsShow) {
				// delayHideControls();
				// hideControls();
			} else {
				// showControls();
				// mHandler.sendEmptyMessageDelayed(MSG_HIDE_CONTROLS,
				// HIDE_CONTROLS_DELAY);
			}

			return true;
		}

		@Override
		public boolean onDoubleTap(MotionEvent e) {
			if (mPaused) {
				return false;
			}
			ImageViewTouch imageView = getCurrentImageView();
			// Switch between the original scale and 3x scale.
			if (imageView.mBaseZoom < 1) {
				if (imageView.getScale() > 2F) {
					imageView.zoomTo(1f);
				} else {
					imageView.zoomToPoint(3f, e.getX(), e.getY());
				}
			} else {
				if (imageView.getScale() > (imageView.mMinZoom + imageView.mMaxZoom) / 2f) {
					imageView.zoomTo(imageView.mMinZoom);
				} else {
					imageView.zoomToPoint(imageView.mMaxZoom, e.getX(), e.getY());
				}
			}
			return true;
		}
	}

	/**
	 * 缩放手势
	 * 
	 * @author zjingchuan
	 * 
	 */
	private class MyOnScaleGestureListener extends
			ScaleGestureDetector.SimpleOnScaleGestureListener {

		float currentScale;
		float currentMiddleX;
		float currentMiddleY;

		@Override
		public void onScaleEnd(ScaleGestureDetector detector) {
			final ImageViewTouch imageView = getCurrentImageView();
			if (currentScale > imageView.mMaxZoom) {
				imageView.zoomToNoCenterWithAni(currentScale / imageView.mMaxZoom, 1,
						currentMiddleX, currentMiddleY);
				currentScale = imageView.mMaxZoom;
				imageView.zoomToNoCenterValue(currentScale, currentMiddleX, currentMiddleY);
			} else if (currentScale < imageView.mMinZoom) {
				imageView.zoomToNoCenterWithAni(currentScale, imageView.mMinZoom, currentMiddleX,
						currentMiddleY);
				currentScale = imageView.mMinZoom;
				imageView.zoomToNoCenterValue(currentScale, currentMiddleX, currentMiddleY);
			} else {
				imageView.zoomToNoCenter(currentScale, currentMiddleX, currentMiddleY);
			}

			imageView.center(true, true);

			// NOTE: 延迟修正缩放后可能移动问题
			imageView.postDelayed(new Runnable() {
				@Override
				public void run() {
					mOnScale = false;
				}
			}, 300);
			// Log.d(TAG, "gesture onScaleEnd");
		}

		@Override
		public boolean onScaleBegin(ScaleGestureDetector detector) {
			// Log.d(TAG, "gesture onScaleStart");
			mOnScale = true;
			return true;
		}

		@Override
		public boolean onScale(ScaleGestureDetector detector, float mx, float my) {
			// Log.d(TAG, "gesture onScale");
			ImageViewTouch imageView = getCurrentImageView();
			float ns = imageView.getScale() * detector.getScaleFactor();

			currentScale = ns;
			currentMiddleX = mx;
			currentMiddleY = my;

			if (detector.isInProgress()) {
				imageView.zoomToNoCenter(ns, mx, my);
			}
			return true;
		}
	}

	/**
	 * pagerAdapter适配器
	 * 
	 * @author zjingchuan
	 * 
	 */
	private class ImagePagerAdapter extends PagerAdapter {
		public Map<Integer, ImageViewTouch> views = new HashMap<Integer, ImageViewTouch>();

		@Override
		public int getCount() {
			// Log.d(TAG, "getCount");
			return mImageList.size();
		}

		@Override
		public Object instantiateItem(View container, int position) {
			 Log.d(TAG, "instantiateItem");
			final ImageViewTouch imageView = new ImageViewTouch(getActivity());
			imageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
					LayoutParams.FILL_PARENT));
			imageView.setBackgroundColor(Color.BLACK);
			imageView.setFocusableInTouchMode(true);
			String url = HttpUtil.BASE_URL+"/image/"+mImageList.get(position);
			Log.v(TAG,"图片地址："+ url);
			Bitmap b = ImageCacheManager.getInstance(getActivity()).getBitmap(
					url, new ImageLoadCallBack() {

						@Override
						public void onImageLoaded(final Bitmap bitmap) {
							getActivity().runOnUiThread(new Runnable() {

								@Override
								public void run() {
									imageView.setImageBitmapResetBase(bitmap, true);
								}

							});
						}

						@Override
						public void onImageLoadErr() {
							// TODO Auto-generated method stub
							getActivity().runOnUiThread(new Runnable() {

								@Override
								public void run() {
									Toast.makeText(getActivity(), "加载失败", Toast.LENGTH_SHORT).show();
									imageView.setImageBitmapResetBase(BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.bg), true);
								}

							});
						}

					});
			if (b != null) {
				imageView.setImageBitmapResetBase(b, true);
			}else {
				imageView.setImageBitmapResetBase(BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.bg), true);
			}
				
			((ViewPager) container).addView(imageView);
			views.put(position, imageView);

			return imageView;
		}

		@Override
		public void destroyItem(View container, int position, Object object) {
			Log.d(TAG, "destroyItem");
			ImageViewTouch imageView = (ImageViewTouch) object;
//			imageView.mBitmapDisplayed.recycle();
//			imageView.clear();
			((ViewPager) container).removeView(imageView);
			views.remove(position);
		}

		@Override
		public void startUpdate(View container) {
			Log.d(TAG, "startUpdate");
		}

		@Override
		public void finishUpdate(View container) {
			 Log.d(TAG, "finishUpdate");
		}

		@Override
		public boolean isViewFromObject(View view, Object object) {
			 Log.d(TAG, "isViewFromObject");
			return view == ((ImageViewTouch) object);
		}

		@Override
		public Parcelable saveState() {
			 Log.d(TAG, "saveState");
			return null;
		}

		@Override
		public void restoreState(Parcelable state, ClassLoader loader) {
			 Log.d(TAG, "restoreState");
		}
	}

	/**
	 * 获得当前图片的uri
	 * 
	 * @return
	 */
	private Uri getCurrentImageUri() {
		File file = new File(mImageList.get(mPosition));
		return Uri.fromFile(file);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_others:

			break;
		case R.id.btn_self:

			break;
		// case R.id.share: {
		// getMoreDialog().dismiss();
		//
		// Intent intent = new Intent(Intent.ACTION_SEND);
		// intent.putExtra(Intent.EXTRA_STREAM, getCurrentImageUri());
		// intent.addCategory(Intent.CATEGORY_DEFAULT);
		// intent.setType("image/*");
		// startActivity(intent);
		// }
		// break;
		}
	}
}
